#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Newtonsoft.Utilities.Testing;
using NUnit.Framework;
using System.Xml;

namespace Newtonsoft.Utilities.Tests.Testing
{
  public class RandomValueCreatorTests : TestsBase
  {
    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Argument cannot be negative.
Parameter name: value
Actual value was -1.")]
    public void MinimumValueNegative()
    {
      RandomValueCreator creator = new RandomValueCreator();
      creator.MinimumStringLength = -1;
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"MinimumStringLength cannot be greater than MaximumStringLength.
Parameter name: value
Actual value was 10.")]
    public void MinimumValueGreaterThanMaximum()
    {
      RandomValueCreator creator = new RandomValueCreator();
      creator.MinimumStringLength = int.MaxValue;
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"MinimumStringLength cannot be greater than MaximumStringLength.
Parameter name: value
Actual value was 0.")]
    public void MaximumValueLessThanMinimumValue()
    {
      RandomValueCreator creator = new RandomValueCreator();
      creator.MinimumStringLength = 1;
      creator.MaximumStringLength = 0;
    }

    [Test]
    public void CreateValue()
    {
      IValueCreator creator = new RandomValueCreator();
      Assert.IsInstanceOfType(typeof(int), creator.CreateValue(typeof(int)));
      Assert.IsInstanceOfType(typeof(Guid), creator.CreateValue(typeof(Guid)));
      Assert.AreNotEqual(Guid.Empty, creator.CreateValue(typeof(Guid)));
      Assert.IsInstanceOfType(typeof(StringComparison), creator.CreateValue(typeof(StringComparison)));
      Assert.IsTrue(Enum.IsDefined(typeof(StringComparison), creator.CreateValue(typeof(StringComparison))));
      Assert.IsInstanceOfType(typeof(TimeSpan), creator.CreateValue(typeof(TimeSpan)));
    }

    [Test]
    public void CreateValueString()
    {
      RandomValueCreator creator = new RandomValueCreator();
      creator.MinimumStringLength = 5;
      creator.MaximumStringLength = 5;

      string randomString = (string)creator.CreateValue(typeof(string));
      Assert.IsNotNull(randomString);
      Assert.AreEqual(5, randomString.Length);

      creator.MinimumStringLength = 5;
      creator.MaximumStringLength = 50;

      for (int i = 0; i < 100; i++)
      {
        randomString = (string)creator.CreateValue(typeof(string));
        Assert.GreaterOrEqual(randomString.Length, creator.MinimumStringLength);
        Assert.LessOrEqual(randomString.Length, creator.MaximumStringLength);
      }
    }

    [Test]
    [ExpectedException(typeof(Exception), ExpectedMessage = @"Cannot create random value for type System.Reflection.Assembly.")]
    public void CreateValueBadType()
    {
      IValueCreator creator = new RandomValueCreator();

      creator.CreateValue(typeof(Assembly));
    }

    [Test]
    public void CanCreateValue()
    {
      IValueCreator creator = new RandomValueCreator();
      Assert.AreEqual(true, creator.CanCreateValue(typeof(int)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(Guid)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(StringComparison)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(int)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(TimeSpan)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(object)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(DateTime)));
      Assert.AreEqual(true, creator.CanCreateValue(typeof(XmlDocument)));
    }
  }
}